5. 포트 기반 보안의 한계와 현대적 접근

UNIX 권한 포트 보안 모델

UNIX 보안 모델의 배경

1970-80년대 컴퓨팅 환경

당시는 현재와 완전히 다른 컴퓨팅 환경이었음:

보안 문제와 해결책

문제 상황:

공용 UNIX 서버의 보안 문제:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[공용 UNIX 서버]

┌───────┼───────┐
│ │ │
↓ ↓ ↓
[일반 [일반 [일반
사용자 A] 사용자 B] 사용자 C]

[악의적 사용자 B]

[가짜 FTP 서버 실행]
포트 21에서 대기

[다른 사용자 로그인 시]
패스워드 탈취

공용 서버에서 악의적 사용자가 정상적인 FTP 서비스인 것처럼 가장하여 다른 사용자의 로그인 정보를 훔치는 상황.

해결책 - 권한 포트 (Privileged Port):

신뢰 체계의 작동 원리:

권한 포트 신뢰 체계:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[클라이언트] → [포트 1024 이하 접속] → [root 권한 확인] →
[시스템 관리자 승인된 서비스임을 보장] → [서비스 신뢰]

이 흐름은 "권한 포트를 사용한다 = 시스템 관리자가 승인했다 = 신뢰할 수 있다"는 논리.

권한 분리 패턴

전통적인 웹서버의 보안 동작

전통적인 웹서버 보안 동작:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[시스템 부팅]

[root로 Apache 마스터 프로세스 시작]

[포트 80/443에 바인딩]

[www-data 사용자로 권한 변경]

[워커 프로세스들 생성]
실제 요청 처리는 www-data 권한

Apache나 Nginx 같은 전통적 웹서버가 어떻게 보안을 구현하는지 보여줌

실제 프로세스 구조:

root      1234  Apache 마스터 프로세스 (포트 바인딩용)
www-data  1235  ├── Apache 워커 #1 (실제 웹 서비스)
www-data  1236  ├── Apache 워커 #2 (실제 웹 서비스)
www-data  1237  └── Apache 워커 #3 (실제 웹 서비스)

권한 분리의 보안 논리

권한 분리의 보안 논리:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

정상 동작:
[포트 바인딩] → [권한 즉시 포기] → [실제 서비스]
root 권한 필요 www-data로 변경 제한된 권한으로 실행

해킹 시:
[해커가 웹서버 해킹] → [www-data 권한만 탈취] → [시스템 전체 장악 불가]
피해 제한

위 다이어그램의 핵심은 권한 최소화 원칙

현대 개발에서의 문제점

Node.js/Python 개발자들의 딜레마

개발자의 딜레마:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

경로 1: 권한 포트 사용
[개발자]

"포트 80에서 테스트하고 싶어"

"sudo로 실행해야 함"

"전체 애플리케이션이 root 권한"

"보안 위험 증가"

경로 2: 비권한 포트 사용
"대안: 포트 8080 사용"

"개발/운영 환경 차이"

"배포 시 설정 복잡"

이 다이어그램은 현대 개발자들이 직면하는 진퇴양난을 보여줌:

구체적 문제 예시:

// Node.js 웹서버 - 포트 80 사용 시
const app = require('express')();
app.listen(80); // ❌ sudo node server.js 필요
# Python Flask - 포트 80 사용 시
from flask import Flask
app = Flask(__name__)
app.run(port=80) # ❌ sudo python app.py 필요 

현대적 해결 방안

1. 리버스 프록시 패턴

리버스 프록시 패턴:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[클라이언트] →(포트 80)→ [Nginx] →(포트 8080)→ [Node.js 앱]
root로 시작 일반 사용자 권한
www-data로 실행

이 구조는 책임 분리를 통한 해결책:

장점:

2. 포트 포워딩/리다이렉션

# iptables를 사용한 포트 리다이렉션
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080

포트 포워딩/리다이렉션:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[클라이언트 요청]
포트 80

[iptables 규칙]

[포트 8080으로 자동 리다이렉션]

[Node.js 앱]
일반 사용자 권한

이 방법은 커널 레벨에서 포트 변환을 수행

3. Docker 컨테이너 격리

FROM node:18-alpine
RUN adduser -S appuser  # 일반 사용자 생성
USER appuser           # 일반 사용자로 전환
EXPOSE 3000            # 비권한 포트 사용
CMD ["node", "server.js"]

Docker 컨테이너 격리:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[Docker Host]

[포트 매핑: 80:3000]

[컨테이너 내부: 포트 3000]

[Node.js 앱]
appuser 권한

Docker를 사용한 격리 기반 보안:

4. Linux Capabilities 시스템

# 특정 프로그램에만 권한 포트 바인딩 허용
sudo setcap CAP_NET_BIND_SERVICE=+eip /usr/bin/node

# 이후 일반 사용자로도 실행 가능
node server.js  # sudo 없이 포트 80 사용 가능

이는 세밀한 권한 제어를 가능하게 함:

보안 모델의 변화

시대별 보안 접근법의 진화

시대별 보안 접근법의 진화:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[1980년대: 멀티유저 시스템]

[포트 기반 신뢰]

[1990-2000년대: 웹서버 시대]

[권한 분리 패턴]

[2010년대: 클라우드/컨테이너]

[격리 기반 보안]

[현재: Zero Trust]

[모든 접근 검증]

패러다임의 근본적 변화